package com.breaktian.assemble.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * Created by zerup on 17/6/6.
 */

public class BitmapUtil {
    //fileName or url
    public static Bitmap getBitmap(String fileName) {
        BitmapFactory.Options options = getOption(fileName);
        return getBitmapSafely(options, fileName);
    }

    public static Bitmap getSampleBitmap(String fileName, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = getOption(fileName);
        int sampleSize = getSampleSize(options, reqWidth, reqHeight);
        options.inSampleSize = sampleSize;
        return getBitmapSafely(options, fileName);
    }

    public static byte[] getBytes(Bitmap bitmap) {
        if (bitmap == null || bitmap.isRecycled()) {
            return null;
        }
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;
    }

    private static Bitmap getBitmapSafely(BitmapFactory.Options options, String fileName) {
        if (options == null) {
            return null;
        }
        options.inJustDecodeBounds = false;
        options.inPreferQualityOverSpeed = true;
        Bitmap bitmap = null;
        try {
            if (PathUtil.isUrl(fileName)) {
                InputStream inputStream = new URL(fileName).openStream();
                bitmap = BitmapFactory.decodeStream(inputStream, null, options);
                inputStream.close();
            } else {
                bitmap = BitmapFactory.decodeFile(fileName, options);
            }
        } catch (Exception e) {
            LogUtil.e(e.getMessage());
        } catch (OutOfMemoryError error) {
            LogUtil.e(error.getMessage());
            options.inSampleSize = options.inSampleSize * 2;
            bitmap = BitmapFactory.decodeFile(fileName, options);
        }
        return bitmap;
    }

    private static BitmapFactory.Options getOption(String fileName) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        if (PathUtil.isUrl(fileName)) {
            try {
                InputStream inputStream = new URL(fileName).openStream();
                BitmapFactory.decodeStream(inputStream, null, options);
                inputStream.close();
            } catch (Throwable e) {
                LogUtil.e(e.getMessage());
            }
        } else {
            BitmapFactory.decodeFile(fileName, options);
        }
        return options;
    }

    private static int getSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        options.inJustDecodeBounds = true;
        int inSampleSize = 1;

        if ((reqHeight > 0 && height > reqHeight) || (reqWidth > 0 && width > reqWidth)) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio;

            while (height > reqHeight * inSampleSize || width > reqWidth * inSampleSize) {
                inSampleSize++;
            }
        }
        return inSampleSize;
    }

    public static void recycle(Bitmap bitmap) {
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }

    public static void saveAsFile(Bitmap bitmap, String filename) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filename);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
            // PNG is a lossless format, the compression factor (100) is ignored
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
